home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 142
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan).7z
/
Gekkan Dennou Club - 2000.3 Vol. 142 (Japan) (Track 1).bin
/
tools
/
s44play
/
s44p101s.lzh
/
interrupt.s
< prev
next >
Wrap
Text File
|
2000-01-23
|
16KB
|
684 lines
.include iocscall.mac
.include keyconst.equ
.include global.mac
.ifndef _LEDCTRL
_LEDCTRL equ $06
.endif
.ifndef _KEYDLY
_KEYDLY equ $08
.endif
.ifndef _KEYREP
_KEYREP equ $09
.endif
;----------------------------------------------------------------
;TRAP#14例外処理ルーチン
; 白窓が出ても意味がないので無条件に中断する
.text
.align 4,$2048
trap14_routine::
DI
bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b trap14_aborted
move.w d7,trap14_d7
move.l a5,trap14_a5
move.w (a6),trap14_sr ;SR
move.l (2,a6),trap14_pc ;PC
move.l #trap14_sr,trap14_a6 ;スタックは破壊されるのでワークにコピーして使う
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
rte ;ダミー
.data
trap14_aborted:: .dc.b 0
.bss
.even
trap14_d7: .ds.w 1
trap14_a5: .ds.l 1
trap14_a6: .ds.l 1
trap14_sr: .ds.w 1
trap14_pc: .ds.l 1
;----------------------------------------------------------------
;TRAP#14でアボートしたときのメッセージの表示
.text
.align 4,$2048
print_trap14_message::
lea.l (m_program_head,pc),a0
bsr eprint
move.l #program_head,d0
bsr h8tos_eprint
bsr ecrlf
move.w trap14_d7,d7 ;TRAP#14に渡されたd7
movea.l trap14_a5,a5 ;TRAP#14に渡されたa5
movea.l trap14_a6,a6 ;TRAP#14に渡されたa6
bsr get_trap14_message
bra eprint
m_program_head: .dc.b 'PROGRAM_HEAD=$',0
.even
;----------------------------------------------------------------
;NMI割り込みルーチン
.text
.align 4,$2048
nmi_routine::
DI
move.b #$0C,SYS_3 ;NMIリセット
;ここでTIMERD割り込みを止めないと重すぎて戻れなくなることがある
bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
.if NMI_PC
move.l (2,sp),nmi_pc
.endif
nmi_routine_proc:
.if 0
sne.b -(sp)
st.b nmi_aborted
movem.l d0-d7/a0-a6,-(sp)
move.w #$301F,d7
lea.l (4*15+2,sp),a6
trap #14
movem.l (sp)+,d0-d7/a0-a6
sf.b nmi_aborted
tst.b (sp)+
beq @f
bset.b #4,IMRB ;TIMERD割り込み許可
@@: rte
.else
;NMIから復帰しても矩形波の位相がずれてしまうので復帰せずにいきなり中断する
st.b nmi_aborted
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
rte ;ダミー
.endif
.data
.align 4
nmi_old_vector:: .dc.l 0
.data
nmi_aborted:: .dc.b 0
.even
abort_iocs_in_progress:: .dc.w -1
.bss
.if NMI_PC
.align 4
nmi_pc: .ds.l 1
.endif
;----------------------------------------------------------------
;POWER OFF割り込みルーチン
; TIMERD割り込みを止めてからアボートする
; ここではPOWER OFF動作は行わない
; (ROMのPOWER OFFルーチンがTIMERCのカウンタを使っているので,
; POWER OFF動作を行うならTIMERCのモードを復元しておく必要がある)
.text
.align 4,$2048
poweroff_routine::
DI
bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b poweroff_aborted
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
rte ;ダミー
.data
.align 4
poweroff_old_vector:: .dc.l 0
.data
poweroff_aborted:: .dc.b 0
;----------------------------------------------------------------
;キー入力バッファフル割り込みルーチン(extraモードでないとき)
; TIMERD割り込みよりもキー入力割り込みの方が強いので
; TIMERDが重くてもキー入力で中断できる
.text
.align 4,$2048
keyin_full_routine::
DI
;キー入力割り込みは復帰する場合が多いので,
;最初にTIMERD割り込みを禁止してはならない
move.l d0,-(sp)
move.b UDR,d0 ;UDRをリード
cmp.b #KEY_CODE_F,d0 ;Fならフェードアウト
beq 6f
cmp.b #KEY_CODE_TAB,d0 ;TABならスキップ
beq 7f
cmp.b #KEY_CODE_ESC,d0 ;ESCなら中止
beq 1f
cmp.b #KEY_CODE_Q,d0 ;Qなら中止
beq 8f
cmp.b #KEY_CODE_BREAK,d0 ;BREAKなら強制中止
beq 2f
cmp.b #KEY_CODE_COPY,d0 ;COPYはINTERRUPTとみなす
beq 15f
cmp.b #KEY_CODE_CTRL,d0 ;CTRL down
beq 3f
cmp.b #KEY_CODE_CTRL|$80,d0 ;CTRL up
beq 4f
cmp.b #KEY_CODE_C,d0 ;C
beq 5f
99: move.l (sp)+,d0
rte
;ESCが押された
1: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b esc_aborted
bra 99b ;すぐにはアボートしない
;BREAKが押された
2: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b break_aborted
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
rte ;ダミー
;CTRLが押された
3: st.b ctrl_down
bra 99b
;CTRLが離された
4: sf.b ctrl_down
bra 99b
;Cが押された
5: tst.b ctrl_down
beq 99b
bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b ctrlc_aborted
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
rte ;ダミー
;Fが押された
6: st.b fadeout_requested
bra 99b
;TABが押された
7: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b tab_aborted
bra 99b ;すぐにはアボートしない
;Qが押された
8: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
move.b #-2,esc_aborted
bra 99b ;すぐにはアボートしない
;COPYが押された
15: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
.if NMI_PC
move.l (4+2,sp),nmi_pc ;スタック注意
.endif
bra nmi_routine_proc ;INTERRUPTとして処理する
.data
.align 4
keyin_full_old_vector:: .dc.l 0
.data
esc_aborted:: .dc.b 0 ;-1=ESCが押された,-2=Qが押された
break_aborted:: .dc.b 0 ;-1=BREAKが押された
ctrlc_aborted:: .dc.b 0 ;-1=CTRL+Cが押された
ctrl_down: .dc.b 0 ;-1=CTRLキーが押されている
fadeout_requested:: .dc.b 0 ;-1=フェードアウトの要求があった
tab_aborted:: .dc.b 0 ;-1=TABが押された
;----------------------------------------------------------------
;muteする
; スーパーバイザモードで呼び出すこと
.text
.align 4,$2048
do_mute:
movem.l d0-d1/a0-a1,-(sp)
lea.l OPMADR,a0
lea.l (OPMDAT-OPMADR,a0),a1
moveq.l #$78,d0
moveq.l #4-1,d1
tst.b mono_play_flag
bne @f
moveq.l #8-1,d1
@@:
1: bsr 70f
move.b d0,(a0)
bsr 70f
move.b #ZERO_TL,(a1)
addq.b #1,d0
dbra d1,1b
bsr 70f
movem.l (sp)+,d0-d1/a0-a1
rts
70: nop
nop
@@: tst.b (a1)
bmi @b
rts
;----------------------------------------------------------------
;キー入力割り込みルーチン(extraモードのとき)
; キーマトリクスと操作の状態を更新する.
; このルーチンでは,同じボタン操作になるキーを2つ同時に押しているとき,
; 一方を離すとそのボタンが離されたと認識される.
; TIMERD割り込みよりもキー入力割り込みの方が強いので,
; TIMERDが重くてもキー入力で中断できる.
.text
.align 4,$2048
extra_keyin_full_routine::
movem.l d1/a0,-(sp)
moveq.l #$01,d1
add.b UDR,d1
beq 10f
subq.b #$01,d1
bmi 1f
.if TEST_BREAK
cmp.b #KEY_CODE_BREAK,d1 ;BREAK
beq 20f
.endif
.if TEST_COPY_INTERRUPT
cmp.b #KEY_CODE_COPY,d1 ;COPYはINTERRUPTとみなす
beq 15f
.endif
.if TEST_ESC
cmp.b #KEY_CODE_ESC,d1 ;ESC
beq 30f
.endif
lea.l (key_stat_table,pc),a0
st.b (a0,d1.w)
move.b (key_mode_table-key_stat_table,a0,d1.w),d1
or.b d1,keyin_status
99: movem.l (sp)+,d1/a0
.if TEST_KEYIN_FULL_OLD
move.l extra_keyin_full_old_vector,-(sp)
rts
.else
rte
.endif
1: lea.l (key_stat_table-128,pc),a0
sf.b (a0,d1.w)
move.b (key_mode_table-key_stat_table,a0,d1.w),d1
not.b d1
and.b d1,keyin_status
movem.l (sp)+,d1/a0
.if TEST_KEYIN_FULL_OLD
move.l extra_keyin_full_old_vector,-(sp)
rts
.else
rte
.endif
;キーボードの初期化
; あまり好ましくないが,IOCSコールで済ませる.
10: move.l d0,-(sp)
move.b $0810.w,d1
IOCS _LEDCTRL
move.b $00ED003A,d1 ;キーリピートのディレイタイム
IOCS _KEYDLY
move.b $00ED003B,d1 ;キーリピートのインターバル
IOCS _KEYREP
movem.l (sp)+,d0-d1/a0
rte
.if TEST_BREAK
;BREAKが押された
20: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b break_aborted
move.w $0A0E.w,abort_iocs_in_progress
IOCS _ABORTRST
IOCS _ABORTJOB
.endif
.if TEST_ESC
;ESCが押された
30: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
st.b esc_aborted
bra 99b
.endif
.if TEST_COPY_INTERRUPT
;COPYが押された
15: bclr.b #4,IMRB ;TIMERD割り込み禁止
bsr do_mute ;muteする
.if NMI_PC
move.l (4*2+2,sp),nmi_pc ;スタック注意
.endif
bra nmi_routine_proc ;INTERRUPTとして処理する
.endif
.align 4
key_mode_table:
; bit0 Forward $01 ↑,8
; bit1 Backward $02 ↓,2
; bit2 Left $04 ←,4
; bit3 Right $08 →,6
; bit5 Trigger-A(右) $20 CR,SP,ENTER,XF1,OPT.1
; bit6 Trigger-B(左) $40 ESC,BS,XF2,OPT.2
; +$00 +$01 +$02 +$03 +$04 +$05 +$06 +$07
; なし ESC 1! 2" 3# 4$ 5% 6&
.dc.b $00, $40, $00, $00, $00, $00, $00, $00 ;$00+
; 7' 8( 9) 0 -= ^~ \| BS
.dc.b $00, $00, $00, $00, $00, $00, $00, $40 ;$08+
; TAB Q W E R T Y U
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$10+
; I O P @` [{ CR A S
.dc.b $00, $00, $00, $00, $00, $20, $00, $00 ;$18+
; D F G H J K L ;+
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$20+
; :* ]} Z X C V B N
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$28+
; M ,< .> /? _ SP HOME DEL
.dc.b $00, $00, $00, $00, $00, $20, $00, $00 ;$30+
; R.UP R.DOWN UNDO ← ↑ → ↓ CLR
.dc.b $00, $00, $00, $04, $01, $08, $02, $00 ;$38+
; / * - 7 8 9 + 4
.dc.b $00, $00, $00, $00, $01, $00, $00, $04 ;$40+
; 5 6 = 1 2 3 ENTER 0
.dc.b $00, $08, $00, $00, $02, $00, $20, $00 ;$48+
; , . 記号 登録 HELP XF1 XF2 XF3
.dc.b $00, $00, $00, $00, $00, $20, $40, $00 ;$50+
; XF4 XF5 かな ローマ コード CAPS INS ひら
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$58+
; 全角 BREAK COPY F1 F2 F3 F4 F5
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$60+
; F6 F7 F8 F9 F10 なし なし なし
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$68+
; SHIFT CTRL OPT.1 OPT.2 NUM なし なし なし
.dc.b $00, $00, $20, $40, $00, $00, $00, $00 ;$70+
; なし なし なし なし なし なし なし なし
.dc.b $00, $00, $00, $00, $00, $00, $00, $00 ;$78+
key_stat_table: .dcb.b 128,0 ;現在のキーの押し下げ状態
.data
keyin_status: .dc.b 0 ;現在のキー操作の状態
; 押されているビットが1
; bit0 Forward
; bit1 Backward
; bit2 Left
; bit3 Right
; bit5 Trigger-A(右)
; bit6 Trigger-B(左)
.if TEST_BREAK
.if 0
break_aborted: .dc.b 0
.endif
.endif
;----------------------------------------------------------------
;TIMERA割り込みルーチン
.text
.align 4,$2048
timera_routine::
.if TIMERA_INTERVAL>1
subq.b #1,timera_interval_counter
beq @f
rte
@@: move.b #TIMERA_INTERVAL,timera_interval_counter
.endif
bclr.b #5,IERA ;TIMERA割り込み禁止
.if TEST_ABSOLUTE
movem.l d0-d1/a0-a1,-(sp)
;割り込み許可
move.w (4*4,sp),d0 ;割り込む前のsr(スタックオフセット注意)
.else
movem.l d0-d1/a0-a1/a6,-(sp)
lea.l base,a6
;割り込み許可
move.w (4*5,sp),d0 ;割り込む前のsr(スタックオフセット注意)
.endif
or.w #$2000,d0
move.w d0,sr ;割り込む前の割り込み許可レベルにする
move.b #%11011111,ISRA ;TIMERA割り込みサービス終了宣言
;カウンタを更新する
tst.w (timera_fadeout_counter)r
ble @f
subq.w #1,(timera_fadeout_counter)r
@@:
sf.b (control_status)r
;キーボードの状態を記録する
clr.w d0
move.b (keyin_status)r,d0 ;今回押されているビットが1
move.b (key_status)r,d1 ;前回押されていたビットが1
not.b d1 ;前回押されていなかったビットが1
move.b d0,(key_status)r ;今回押されているビットが1
and.b d1,d0 ;今回押されたビットが1
beq @f
or.b d0,(control_status)r
bsr writeControl
@@:
;パッドの状態を記録する
move.w #$01_00,d0
move.b JOY1,d0 ;今回押されていないビットが1
move.b (joy1_status)r,d1 ;前回押されていたビットが1
not.b d0 ;今回押されているビットが1
not.b d1 ;前回押されていなかったビットが1
move.b d0,(joy1_status)r ;今回押されているビットが1
and.b d1,d0 ;今回押されたビットが1
beq @f
or.b d0,(control_status)r
bsr writeControl
@@:
move.w #$02_00,d0
move.b JOY2,d0 ;今回押されていないビットが1
move.b (joy2_status)r,d1 ;前回押されていたビットが1
not.b d0 ;今回押されているビットが1
not.b d1 ;前回押されていなかったビットが1
move.b d0,(joy2_status)r ;今回押されているビットが1
and.b d1,d0 ;今回押されたビットが1
beq @f
or.b d0,(control_status)r
bsr writeControl
@@:
;マウスの状態を記録する
move.l d2,-(sp)
move.b (mouse_status)r,d1 ;前回押されていたビットが1
not.b d1 ;前回押されていなかったビットが1
lea.l $0930.w,a0
moveq.l #%00000011,d0
and.b (a0)+,d0 ;[$0930.w].b:マウスステータスデータ
; bit0 左スイッチ(0=OFF,1=ON)
; bit1 右スイッチ(0=OFF,1=ON)
; bit4 オーバーフロー(X>127)
; bit5 オーバーフロー(X<-128)
; bit6 オーバーフロー(Y>127)
; bit7 オーバーフロー(Y<-128)
;bit1:マウスの右スイッチ(0=OFF,1=ON)
;→bit6:Trigger-B(左)
;bit0:マウスの左スイッチ(0=OFF,1=ON)
;→bit5:Trigger-A(右)
add.b d0,d0 ;bit4
moveq.l #$80,d2
add.b (a0)+,d2 ;[$0931.w].b:マウスの左右移動量(+右,-左)
;$00~$7F=左,$81~$FF=右
add.b #$80-MOUSE_DELTA,d2 ;$80+MOUSE_DELTA~$FFのときcs
addx.b d0,d0 ;bit3:右
sub.b #$80-MOUSE_DELTA,d2 ;元に戻す
sub.b #$80-MOUSE_DELTA,d2 ;$00~$80-MOUSE_DELTAのときcs
addx.b d0,d0 ;bit2:左
moveq.l #$80,d2
add.b (a0)+,d2 ;[$0932.w].b:マウスの上下移動量(+下,-上)
;$00~$7F=上,$81~$FF=下
add.b #$80-MOUSE_DELTA,d2 ;$80+MOUSE_DELTA~$FFのときcs
addx.b d0,d0 ;bit1:下
sub.b #$80-MOUSE_DELTA,d2 ;元に戻す
sub.b #$80-MOUSE_DELTA,d2 ;$00~$80-MOUSE_DELTAのときcs
addx.b d0,d0 ;bit0:上
move.b d0,(mouse_status)r
and.b d1,d0 ;今回押されたビットが1
beq @f
or.b d0,(control_status)r
or.w #$03_00,d0
bsr writeControl
@@: move.l (sp)+,d2
.if TEST_CONTROL
moveq.l #%00100000,d0 ;Trigger-A(右)
and.b (control_status)r,d0
bne 1f
move.w #$0000,$00E82200
bra 2f
1: move.w #$003E,$00E82200
2:
.endif
;マウスデータを要求する
moveq.l #$20,d0
; and.b IMRB,d0
and.b IERB,d0
bne @f ;TIMERCが生きているときはスキップ
movea.l $09B6.w,a0 ;TIMERCのマウスデータ受信要求処理のアドレス
jsr (a0)
@@:
.if TEST_ABSOLUTE
movem.l (sp)+,d0-d1/a0-a1
.else
movem.l (sp)+,d0-d1/a0-a1/a6
.endif
bset.b #5,IERA ;TIMERA割り込み許可
rte
.data
.if TIMERA_INTERVAL>1
timera_interval_counter: .dc.b TIMERA_INTERVAL
.endif
control_status:: .dc.b 0 ;現在の操作の状態
; 押されているビットが1
; bit0 Forward
; bit1 Backward
; bit2 Left
; bit3 Right
; bit5 Trigger-A(右)
; bit6 Trigger-B(左)
key_status: .dc.b 0
joy1_status: .dc.b 0
joy2_status: .dc.b 0
mouse_status: .dc.b 0
.even
timera_fadeout_counter:: .dc.w -1 ;TIMERA割り込みカウンタ
;1以上の正数のときTIMERA割り込みで1ずつ引かれる
;----------------------------------------------------------------
;操作をバッファに書き込む
;<d0.w:操作
;<a6.l:base
;?a0
.text
.align 4,$2048
writeControl::
cmpi.w #MAX_CONTROL,(control_count)r
beq 9f ;これ以上書き込めない
addq.w #1,(control_count)r ;ライトなので処理の前にカウンタを増やす
movea.l (control_write_ptr)r,a0
move.w d0,(a0)+
cmpa.l #control_record_end,a0
blo @f
lea.l control_record,a0
@@: move.l a0,(control_write_ptr)r
9: rts
;----------------------------------------------------------------
;操作をバッファから読み出す
;<a6.l:base
;>d0.w:操作
; $00xx キーボード
; $01xx JOY1
; $02xx JOY2
; $03xx マウス
; 押されているビットが1
; bit0 Forward
; bit1 Backward
; bit2 Left
; bit3 Right
; bit5 Trigger-A(右)
; bit6 Trigger-B(左)
;>z-flag:eq=操作なし
;?a0
.text
.align 4,$2048
readControl::
move.w (control_count)r,d0
beq 9f ;操作がない
movea.l (control_read_ptr)r,a0
move.w (a0)+,d0
cmpa.l #control_record_end,a0
blo @f
lea.l control_record,a0
@@: move.l a0,(control_read_ptr)r
subq.w #1,(control_count)r ;リードなので処理の後にカウンタを減らす
tst.w d0
9: rts
;----------------------------------------------------------------
;操作のワーク
.data
.even
control_count: .dc.w 0 ;操作のバッファの中の操作の数
.align 4
control_read_ptr: .dc.l control_record
control_write_ptr: .dc.l control_record
.even
.bss
.even
control_record: .dcb.w MAX_CONTROL,0
; $00xx キーボード
; $01xx JOY1
; $02xx JOY2
; $03xx マウス
; 押されているビットが1
; bit0 Forward
; bit1 Backward
; bit2 Left
; bit3 Right
; bit5 Trigger-A(右)
; bit6 Trigger-B(左)
control_record_end: